#include "../code/sistemas.h"

/* Prueba el disparo generado a partir del vector de posición propia y enemiga random. */
int main(int argc, char* argv[])
{
    srand(NULL);
    
    system("rm -f disparoRandomCondMatrices.out");
    
    ofstream salida("disparoRandomDatos.out");
    ofstream matrices("disparoRandomMatrices.out");
    ofstream condMatrices, detMatrices;    
    
    salida.precision(20);
	salida.setf(std::ios_base::scientific, std::ios_base::floatfield);
    matrices.precision(20);
	matrices.setf(std::ios_base::scientific, std::ios_base::floatfield);
    
    ofstream input;

    fornx(n, 2, 51)
    {
		/* Matríz de hilbert. */
		Matriz hil (n, Vector(n));
		Hilbert(hil, n);
		
		/* Generar dos vectores de n */
		Vector v (n); /* pos_propia */
		Vector w (n); /* pos_enemiga */
		
		/* Resultados. */
		Matriz m (n, Vector(n));
		Vector res (n);		
		
		/* La dimensión. */
		salida << n << endl;
		matrices << n << endl;
		
		condMatrices.open ("disparoRandomCondMatrices.out", ios_base::app);		
		condMatrices << n << endl;		
				
		forn(i, 100)		
		{
			/* Llenar los vectores de números random. */				
			generarVector(v, n);	
			generarVector(w, n);
			
			/* Buscar la matríz de disparo. */
			buscarMatriz(m, hil, w, v, n);			
			
			/* Disparar. */
			matrizPorVector(m, v, res, n);				

			/* La distancia euclideana entre el valor de res obtenido y w (valor real). */			
			salida << dist(res, w, n) << " ";
			
			/* Guardar la matríz de disparo utilizada. */			
		    forn(i, n)
		    {
				forn(j, n)
		            matrices << m[i][j] << " ";
		        matrices << endl;
		    }		    
			matrices << endl;
			
			/* Matríz en formato Octave. */
			stringstream aux_m;			
			aux_m << "m = [";			
					
			forn(i, n-1)
		    {
				forn(j, n-1)
		            aux_m << m[i][j] << ", ";
		            
		        aux_m << m[i][n-1] << ";";
		    }
		    
			forn(j, n-1)
				aux_m << m[n-1][j] << ", ";
				
			aux_m << m[n-1][n-1] << "];";
			string matriz;
			matriz = aux_m.str();
			
			/* Calcular el número de condición de la matríz utilizada usando Octave. */
			input.open("input.m", ios_base::trunc);
			input << "close all" << endl;
			input << matriz << endl;			
			input << "printf('%1.20e ', cond(m))" << endl;			
						
			system("octave --quiet < input.m >> disparoRandomCondMatrices.out");			
			input.close();
		}		
		
		salida << endl;
		matrices << endl;
		condMatrices << endl;		
		
		condMatrices.close();		
	}
	
	salida.close();
	matrices.close();	
    
    return 0;
}
